package com.kxxnzstdsw.service.impl

import com.kxxnzstdsw.config.Config
import com.kxxnzstdsw.exception.ExceptionCode
import com.kxxnzstdsw.exception.can.AccountException
import com.kxxnzstdsw.exception.can.InvalidPasswordException
import com.kxxnzstdsw.exception.can.NotFoundException
import com.kxxnzstdsw.modle.dto.LoginParams
import com.kxxnzstdsw.modle.enums.AccountStatus
import com.kxxnzstdsw.modle.repo.AccountRepository
import com.kxxnzstdsw.service.AccountService
import com.kxxnzstdsw.utils.checkCaptcha
import com.kxxnzstdsw.utils.checkPw
import com.kxxnzstdsw.utils.token
import io.lettuce.core.api.StatefulRedisConnection
import kotlinx.coroutines.runBlocking
import org.koin.core.component.inject

class AccountServiceImpl : AccountService {
  private val conf by inject<Config>()
  private val accountRepository by inject<AccountRepository>()
  private val redis by inject<StatefulRedisConnection<String, String>>()

  override fun login(loginParams: LoginParams) = runBlocking {
    redis.checkCaptcha(loginParams.key, loginParams.code)
    val account =
      accountRepository.infoByUsername(loginParams.username) ?: throw NotFoundException(ExceptionCode.A_000002)
    when {
      account.status == AccountStatus.FREEZE -> {
        throw AccountException(
          ExceptionCode.A_000003.tips,
          ExceptionCode.A_000003
        )
      }

      account.status == AccountStatus.CANCEL -> {
        throw AccountException(
          ExceptionCode.A_000006.tips,
          ExceptionCode.A_000006
        )
      }

      !account.password.checkPw(loginParams.password) -> {
        throw InvalidPasswordException()
      }

      else -> {
        conf.jwt.token(getKoin(), account.username, account.id.toString())
      }
    }
  }
}
